package com.sun.huazhi.aitaskservice.common.mq;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.Channel;
import com.sun.huazhi.aitaskservice.common.Enum.TasksStatus;
import com.sun.huazhi.aitaskservice.common.client.PythonVideoApiClient;
import com.sun.huazhi.aitaskservice.dao.entity.ApiLogsDO;
import com.sun.huazhi.aitaskservice.dao.entity.VideoTasksDO;
import com.sun.huazhi.aitaskservice.dao.mapper.ApiLogsMapper;
import com.sun.huazhi.aitaskservice.dao.mapper.VideoTasksMapper;
import com.sun.huazhi.aitaskservice.service.impl.DynamicVideoServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.cfg.RecoverableException;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.time.LocalDateTime;
import java.util.Map;

/**
 *  RabbitMQ 消费者 实现视频生成
 */

@Service
@RequiredArgsConstructor
@Slf4j
public class VideoTaskConsumer {

    private final VideoTasksMapper videoTasksMapper;
    private final ApiLogsMapper apiLogsMapper;
    private final PythonVideoApiClient pythonApiClient;
    private final DynamicVideoServiceImpl dynamicVideoService;
    private final ObjectMapper objectMapper;


    @RabbitListener(queues = "${spring.rabbitmq.queue-names.video-task}") // 配置队列名
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void handleVideoTask(
            Map<String, Object> message,
            Channel channel,
            @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag
    ) throws IOException {

        String taskId = (String) message.get("taskId");
        String prompt = (String) message.get("prompt");
        Long userId = Long.parseLong(message.get("userId").toString());

        try {
            // 幂等性检查：确保任务处于待处理状态
            VideoTasksDO task = videoTasksMapper.selectOne(
                    new LambdaQueryWrapper<VideoTasksDO>()
                            .eq(VideoTasksDO::getTaskId, taskId)
                            .eq(VideoTasksDO::getStatus, TasksStatus.PENDING.name())
            );
            if (task == null) {
                log.warn("任务已处理或不存在: {}", taskId);
                channel.basicAck(deliveryTag, false); // 确认消息避免重复处理
                return;
            }
            updateTaskStatus(taskId, TasksStatus.PROCESSING);

//            // 调用Python API生成视频
//            String videoUrl = pythonApiClient.createVideo(prompt); // 实际调用Python服务
            // 调用Python API生成视频并获取临时文件
            File videoFile = pythonApiClient.generateVideoFile(prompt);

            // 存储到GridFS并更新记录
            dynamicVideoService.storeVideoToGridFS(taskId, videoFile);
            Files.deleteIfExists(videoFile.toPath()); // 添加删除操作 删除本地临时文件

            logApiCall(userId, "video_create_success", 200, "Video generated", message);

            channel.basicAck(deliveryTag, false); // 手动ACK

        } catch (RecoverableException e) {
            log.error("可恢复异常，任务重试 - taskId: {}", taskId, e);
            channel.basicNack(deliveryTag, false, true); // 重试
        } catch (Exception e) {
            log.error("不可恢复异常 - taskId: {}", taskId, e);
            updateTaskStatus(taskId, TasksStatus.FAILED);
            logApiCall(userId, "video_create_failed", 500, e.getMessage());
            channel.basicNack(deliveryTag, false, false); // 丢弃
        }
    }

    private void updateTaskStatus(String taskId, TasksStatus status) {
        VideoTasksDO task = new VideoTasksDO();
        task.setTaskId(taskId);
        task.setStatus(status.name());
        videoTasksMapper.updateById(task);
    }
    //成功时
    private void logApiCall(Long userId, String apiType, int code, String result) {
        ApiLogsDO log = new ApiLogsDO();
        log.setUserId(userId);
        log.setApiType(apiType);
        log.setResponseCode(code);
        log.setResponseData(result);
        log.setCreatedTime(LocalDateTime.now());
        apiLogsMapper.insert(log);
    }
    //失败时
    private void logApiCall(Long userId, String apiType, int code, String result , Map<String, Object> message) throws JsonProcessingException {
        // 转换为 JSON 字符串
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(message);
        ApiLogsDO log = new ApiLogsDO();
        log.setUserId(userId);
        log.setApiType(apiType);
        log.setResponseCode(code);
        log.setResponseData(result);
        log.setCreatedTime(LocalDateTime.now());
        log.setRequestData(json);
        apiLogsMapper.insert(log);
    }
}
